﻿// -
// <copyright file="RelayContext.cs" company="Microsoft Corporation">
//    Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
// -

using System;
using System.Collections.Generic;
using Hawaii.Services.Client.Relay;
using System.Diagnostics;
using Hawaii.Services.Client;

namespace PhoneApp1
{
    /// <summary>
    /// A Container class for all pages.
    /// </summary>
    public class RelayContext
    {

        /// <summary>
        /// Initializes a new instance of the RelayContext class.
        /// </summary>
        public RelayContext()
        {
            this.Endpoint = null;
            this.Groups = new Groups();
            this.Messages = new List<Message>();
        }

        /// <summary>
        /// Gets or sets Endpoint.
        /// </summary>
        public Endpoint Endpoint { get; set; }

        /// <summary>
        /// Gets or sets available (created) groups.
        /// </summary>
        public Groups Groups { get; set; }

        /// <summary>
        /// Gets or sets the messages.
        /// </summary>
        public List<Message> Messages { get; set; }

        /// <summary>
        /// Method creates a relay context from storage.
        /// </summary>
        /// <returns>A valid RelayContext object.</returns>
        public static RelayContext CreateObject()
        {
            RelayContext dataContainer = new RelayContext();
            dataContainer.ReadFromStorage();
            return dataContainer;
        }

        /// <summary>
        /// Save the data into the storage.
        /// </summary>
        public void SaveToStorage()
        {
            try
            {
                RelayStorage.SaveEndpoint(this.Endpoint);
                RelayStorage.SaveGroups(this.Groups);
                RelayStorage.SaveMessages(this.Messages);
            }
            catch (Exception)
            {
                // Let's not to crash the client.
            }
        }

        /// <summary>
        /// Read the data from the storage.
        /// </summary>
        public void ReadFromStorage()
        {
            try
            {
                this.Endpoint = RelayStorage.ReadEndpoint();
                this.Groups = RelayStorage.ReadGroups();
                this.Messages = RelayStorage.ReadMessages();
            }
            catch (Exception)
            {
                // Let's not to crash the client.
            }
        }

        public void SendPollAppMessage(PollAppMessage m)
        {
            if (this.Endpoint == null)
            {
                Debug.WriteLine("ERROR: no endpoint to send from!");
                return;
            }

            // send to all groups (for now at least)
            //string sendto = string.Join(",", ((App)App.Current).fileStorage.df.created_groups.ToArray());
            List<string> groupIds = new List<string>();
            foreach (Group group in this.Endpoint.Groups)
            {
                groupIds.Add(group.RegistrationId);
            }
            string sendto = string.Join(",", groupIds.ToArray());
            Debug.WriteLine("Sending message to group(s): "+sendto);

            // TODO: remove this line:
            //sendto = this.Endpoint.RegistrationId;
            //sendto = "6BFBB2FBE0F2AC38";

            if (string.IsNullOrEmpty(sendto))
            {
                Debug.WriteLine("ERROR: we have no group to send to!!!");
                return;
            }

            

            RelayService.SendMessageAsync(
                HawaiiClient.HawaiiApplicationId,
                this.Endpoint,
                sendto,
                m.getBytes(),
                this.OnCompleteSendMessage);
        }

        private void OnCompleteSendMessage(MessagingResult result)
        {
            if (result.Status == Status.Success)
            {
                //this.DisplayMessage("Sending message to group(s) succeeded.", "Info");
                Debug.WriteLine("Sending message to group(s) succeeded.");
            }
            else
            {
                //this.DisplayMessage("Sending message to group(s) failed.", "Error");
                Debug.WriteLine("ERROR: Sending message to group(s) failed.");
            }
        }

        public void CheckForMessages()
        {
            if (this.Endpoint == null)
            {
                Debug.WriteLine("ERROR: no endpoint to recieve from!");
                return;
            }
            RelayService.ReceiveMessagesAsync(HawaiiClient.HawaiiApplicationId, this.Endpoint, string.Empty, this.receiveMessages);
        }

        private void receiveMessages(MessagingResult result)
        {
            Debug.Assert(result != null, "result is null");
            if (result.Status == Status.Success)
            {
                if (result.Messages == null || result.Messages.Count == 0)
                {
                    //this.DisplayMessage("No new messages available.", "Info");
                    Debug.WriteLine("No new messaged available.");
                }
                else
                {
                    foreach (Message message in result.Messages)
                    {
                        parseNewMessage(message);
                    }

                    //this.Dispatcher.BeginInvoke(new DisplayMessagesDelegate(this.DisplayMessages));
                }
            }
            else
            {
                //this.DisplayMessage("Error receiving messages for active endpoint.", "Error");
                Debug.WriteLine("ERROR: recieveing messages for endpoint!");
            }
        }

        private void parseNewMessage(Message m)
        {
            Debug.WriteLine("Got a new message!");
            DataFile df = ((App)App.Current).fileStorage.df;
            PollAppMessage pm = new PollAppMessage();
            pm.setBytes(m.Body);
            switch (pm.type)
            {
                case PollAppMessageType.newPoll:
                    Debug.WriteLine("Got a Poll message!");
                    Poll p = new Poll();
                    p.setBytes(pm.data);
                    Debug.WriteLine("Poll: " + p.questionText);
                    df.polls.Add(p);
                    break;

                case PollAppMessageType.newVote:
                    Debug.WriteLine("Got a Vote message!");
                    Vote v = new Vote();
                    v.setBytes(pm.data);
                    foreach (Poll poll in df.polls)
                    {
                        if (poll.guid == v.pollGuid)
                        {
                            foreach (Choice c in poll.choices)
                            {
                                if (c.guid == v.choiceGuid)
                                {
                                    Debug.WriteLine("Choice: " + poll.questionText + " -> " + c.choiceText);
                                    c.votes++;
                                    c.voters.Add(v.voter);
                                    break;
                                }
                            }
                            break;
                        }
                    }
                    break;
            }
        }
    }
}
